package com.algorithm.liyc.practice;

/**
 * 移除元素
 * 给你一个数组 nums 和一个值 val，你需要 原地 移除所有数值等于 val 的元素，并返回移除后数组的新长度。
 * 要知道数组的元素在内存地址中是连续的，不能单独删除数组中的某个元素，只能覆盖。
 * 暴力解法 时间复杂度：O(n^2) 空间复杂度：O(1)
 * @author Liyc
 * @date 2023/11/9 11:23
 **/

public class Solution2 {
    /**
     * 快慢指针
     * 时间复杂度：O(n)
     * 空间复杂度：O(1)
     */
    public int removeElement(int[] nums, int val) {
        int startIndx = 0;
        for (int followerIndx = 0; followerIndx < nums.length; followerIndx++) {
            if (nums[followerIndx] != val) {
                nums[startIndx] = nums[followerIndx];
                startIndx++;
            }
        }
        return startIndx;
    }
    /**
     * 相向双指针方法，基于元素顺序可以改变的题目描述改变了元素相对位置，确保了移动最少元素
     * 时间复杂度：O(n)
     * 空间复杂度：O(1)
     */
    public int removeElement1(int[] nums, int val) {
        int left = 0;
        int right = nums.length - 1;
        while(right >= 0 && nums[right] == val) right--; //将right移到从右数第一个值不为val的位置
        while(left <= right) {
            if(nums[left] == val) { //left位置的元素需要移除
                //将right位置的元素移到left（覆盖），right位置移除
                nums[left] = nums[right];
                right--;
            }
            left++;
            while(right >= 0 && nums[right] == val) right--;
        }
        return left;
    }

}
